﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ciloci.Flee.CalcEngine;
using Ciloci.Flee;

namespace Grapher_dot_net
{
    class Function
    {
        public string Expression{get;private  set;}
        ExpressionContext context = new ExpressionContext();
        IDynamicExpression e;

        double? precompute = null;

        const string whitelist = "+-*/^";

        public Function(string expression)
        {

            expression = expression.Replace(" ", "").ToLower();
            string exp = "" + expression[0]; 
            for (int i = 1; i < expression.Length; i++)
            {
                char c = expression[i];
                char p = expression[i - 1];
                
                if (c == 'x')
                {
                    if (!whitelist.Contains(p))
                    {
                        exp += "*x";
                    }
                    else
                        exp += c;
                }
                else
                    exp += c;

            }
           

            this.Expression = exp;
            if (Expression.Contains("x"))
                context.Variables.DefineVariable("x", typeof(double));
            e = context.CompileDynamic(Expression); 
           
            if (!Expression.Contains("x"))
            { 
                try
                {
                    precompute = (double)e.Evaluate();
                }
                catch
                {
                    precompute = (Int64 )e.Evaluate();
                }
            }
        }
        
        public double Evaluate(double input)
        {
            
            try
            {
                if (precompute != null)
                    return (double)precompute;

                context.Variables["x"] = input;
                var result = e.Evaluate();
                return (double)result;

            }
            catch
            {
                return 0;
            }
        }
    }
}
